﻿using System;
using System.Xml.Linq;
using ComTypes = System.Runtime.InteropServices.ComTypes;

namespace NFox.Runtime.Com.Reflection
{
    /// <summary>
    /// 属性信息
    /// </summary>
    public class Property : MemberBase
    {
        internal Property(XElement xe)
            : base(xe)
        {
            CanGet = xe.Attribute("Get") != null;
            if (CanSet = xe.Attribute("Set") != null)
            {
                SetKind =
                    (ComTypes.INVOKEKIND)Enum.Parse(
                        typeof(ComTypes.INVOKEKIND),
                        xe.Attribute("Kind").Value);
            }
        }

        public Property(int id, string name, ComTypes.ITypeInfo info, ComTypes.FUNCDESC desc)
            : base(id, name)
        {
            MergeInvokeKind(desc.invkind);
            if (CanGet)
            {
                Element =
                    new Element(info, desc.elemdescFunc);
            }
            else
            {
                Element =
                    new Element(
                        info,
                        Utils.GetObject<ComTypes.ELEMDESC>(
                            desc.lprgelemdescParam));
            }
        }

        protected override string Category
        {
            get { return "Property"; }
        }

        public override XElement Node
        {
            get
            {
                var node = base.Node;
                if (CanGet)
                {
                    node.Add(new XAttribute("Get", CanGet));
                }
                if (CanSet)
                {
                    node.Add(new XAttribute("Set", CanSet));
                    node.Add(new XAttribute("Kind", SetKind));
                }
                return node;
            }
        }

        public bool CanGet { get; protected set; }

        public bool CanSet { get; protected set; }

        public ComTypes.INVOKEKIND SetKind { get; protected set; }

        public void MergeInvokeKind(ComTypes.INVOKEKIND flag)
        {
            if (flag == ComTypes.INVOKEKIND.INVOKE_PROPERTYGET)
            {
                CanGet = true;
            }
            else
            {
                CanSet = true;
                SetKind = flag;
            }
        }

        public override string ToString()
        {
            var sget = CanGet ? "get;" : "";
            var sset = CanGet ? "set;" : "";
            return $"{Element} {Name} {{ {sget} {sset} }}";
        }
    }
}